package com.biz.primus.ms.payment.service;

import com.biz.primus.common.utils.CopyUtils;
import com.biz.primus.common.utils.JsonUtils;
import com.biz.primus.model.payment.vo.req.AllInPayCardAddReqVo;
import com.biz.primus.model.payment.vo.req.AllInPayCardChangeReqVo;
import com.biz.primus.model.payment.vo.req.AllInPayCardOpenReqVo;
import com.biz.primus.model.payment.vo.resp.AllInPayCardChangePwdRespVo;
import com.biz.primus.model.payment.vo.resp.AllInPayCardOpenAccountRespVo;
import com.biz.primus.model.payment.vo.resp.AllInPayErrorRespVo;
import com.biz.primus.model.payment.vo.resp.AllInPayRechargeRespVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.payment.channel.allinpay.AllInPayPayFactory;
import com.biz.primus.ms.payment.channel.allinpay.config.AllinPayConfig;
import com.biz.primus.ms.payment.channel.allinpay.req.AllInPayCardAdd;
import com.biz.primus.ms.payment.channel.allinpay.req.AllInPayCardChange;
import com.biz.primus.ms.payment.channel.allinpay.req.AllInPayCardOpen;
import com.biz.primus.ms.payment.channel.allinpay.res.*;
import com.biz.primus.ms.payment.dao.po.AllInPayAddLogPo;
import com.biz.primus.ms.payment.dao.po.AllInPayChangeLogPo;
import com.biz.primus.ms.payment.dao.po.AllInPayOpenLogPo;
import com.biz.primus.ms.payment.dao.repository.AllInPayAddLogRepository;
import com.biz.primus.ms.payment.dao.repository.AllInPayChangeLogRepository;
import com.biz.primus.ms.payment.dao.repository.AllInPayOpenLogRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * AllInPayCardService
 * 卡云相关服务
 *
 * @author JKLiues
 * @date 2017年11月13日
 */
@Service
@Slf4j
public class AllInPayCardService extends AbstractBaseService {

    private final AllInPayOpenLogRepository allInPayOpenLogRepository;
    private final AllInPayAddLogRepository allInPayAddLogRepository;
    private final AllInPayChangeLogRepository allInPayChangeLogRepository;

    @Autowired
    public AllInPayCardService(AllInPayOpenLogRepository allInPayOpenLogRepository, AllInPayAddLogRepository allInPayAddLogRepository, AllInPayChangeLogRepository allInPayChangeLogRepository) {
        this.allInPayOpenLogRepository = allInPayOpenLogRepository;
        this.allInPayAddLogRepository = allInPayAddLogRepository;
        this.allInPayChangeLogRepository = allInPayChangeLogRepository;
    }

    /**
     * 卡云充值
     *
     * @param reqVo 充值请求
     * @return ALlInPayCardAddRespVo
     */
    public AllInPayRechargeRespVo addCard(AllInPayCardAddReqVo reqVo) {
        AllInPayPayFactory allInPayPayFactory = AllInPayPayFactory.newInstance();
        AllInPayCardAdd addCard = allInPayPayFactory.newAdd(reqVo);
        String sign = allInPayPayFactory.newSigner().signWithKey2(addCard.getSignParams(), addCard, AllinPayConfig.APP_SECRET);
        AllInPayCardAddDataRespVo execute = addCard.execute(sign);
        ALlInPayCardAddRespVo result = execute.getPpcs_cardsingletopup_add_response();
        AllInPayErrorRespVo error = execute.getError_response();
        if (reqVo != null) {
            AllInPayRechargeRespVo vo = new AllInPayRechargeRespVo();
            AllInPayAddRespItem resultInfo = result.getResult_info();
            vo.setCardNo(resultInfo.getCard_id());
            vo.setAccountBalance(resultInfo.getAccount_balance());
            vo.setValidBalance(resultInfo.getValid_balance());
            vo.setTransNo(result.getTrans_no());
            vo.setValidityDate(resultInfo.getValidity_date());
            log.info("充值成功,写日志--------");
            this.addLog(vo, JsonUtils.obj2Json(result));
            return vo;
        } else {
            return new AllInPayRechargeRespVo(error.getMsg());
        }
    }

    /**
     * 修改卡云密码
     *
     * @param reqVo 修改密码请求
     * @return AllInPayCardChangeRespVo
     */
    public AllInPayCardChangePwdRespVo changePassword(AllInPayCardChangeReqVo reqVo) {
        AllInPayPayFactory allInPayPayFactory = AllInPayPayFactory.newInstance();
        AllInPayCardChange cardChange = allInPayPayFactory.newChange(reqVo);
        String sign = allInPayPayFactory.newSigner().signWithKey2(cardChange.getSignParams(), cardChange, AllinPayConfig.APP_SECRET);
        AllInPayCardChangeDataRespVo execute = cardChange.execute(sign);
        AllInPayCardChangeRespVo result = execute.getCard_password_change_response();
        AllInPayErrorRespVo error_response = execute.getError_response();
        if (result != null) {
            AllInPayCardChangePwdRespVo vo = new AllInPayCardChangePwdRespVo();
            vo.setTransNo(result.getTrans_no());
            vo.setCardNo(result.getCard_id());
            log.info("改密成功,写日志--------");
            this.changeLog(vo, JsonUtils.obj2Json(result));
            return vo;
        } else {
            return new AllInPayCardChangePwdRespVo(error_response.getMsg());
        }
    }

    /**
     * 开卡
     *
     * @param reqVo 请求VO
     * @return AllInPayCardOpenRespVo
     */
    public AllInPayCardOpenAccountRespVo openCard(AllInPayCardOpenReqVo reqVo) {
        AllInPayPayFactory allInPayPayFactory = AllInPayPayFactory.newInstance();
        AllInPayCardOpen cardOpen = allInPayPayFactory.newOpen(reqVo);
        String sign = allInPayPayFactory.newSigner().signWithKey2(cardOpen.getSignParams(), cardOpen, AllinPayConfig.APP_SECRET);
        AllInPayCardOpenDataRespVo execute = cardOpen.execute(sign);
        AllInPayErrorRespVo error_response = execute.getError_response();
        AllInPayCardOpenRespVo result = execute.getPpcs_cloud_card_open_response();
        if (result != null && result.getResult() == 0) {
            AllInPayCardOpenAccountRespVo vo = new AllInPayCardOpenAccountRespVo();
            vo.setMobile(result.getPhone_num());
            vo.setCardNo(result.getCard_id());
            log.info("开卡成功,写日志--------");
            this.openLog(vo, JsonUtils.obj2Json(result));
            return vo;
        } else {
            return new AllInPayCardOpenAccountRespVo(error_response.getMsg());
        }
    }


    private void addLog(AllInPayRechargeRespVo vo, String json) {
        AllInPayAddLogPo logPo = new AllInPayAddLogPo();
        CopyUtils.copyNotNullProperies(vo, logPo);
        logPo.setJsonStr(json);
        logPo.setId(idService.getNextId());
        allInPayAddLogRepository.save(logPo);
    }

    private void openLog(AllInPayCardOpenAccountRespVo vo, String json) {
        AllInPayOpenLogPo logPo = new AllInPayOpenLogPo();
        CopyUtils.copyProperties(vo, logPo);
        logPo.setJsonStr(json);
        logPo.setId(idService.getNextId());
        allInPayOpenLogRepository.save(logPo);
    }

    private void changeLog(AllInPayCardChangePwdRespVo vo, String json) {
        AllInPayChangeLogPo logPo = new AllInPayChangeLogPo();
        CopyUtils.copyProperties(vo, logPo);
        logPo.setId(idService.getNextId());
        logPo.setJsonStr(json);
        allInPayChangeLogRepository.save(logPo);
    }
}